
/* $Id: permuta.c 8 2009-12-27 16:54:50Z calicant $ */

#include "edilana.h"

static char *chouse_n (char *strng, int length)
{
static char *str, *curr, *pos;
static int counts[256];
int i,j;

	if (length <= 0)
		return NULL;

	/* alla prima chiamata fa un po' di preparativi */
	if (NULL != strng) {
		str = malloc(strlen(strng));
		curr = malloc(2 * length + 1);
		pos = curr + length +1;

		for (i = 0; i < 256; counts[i++] = 0) ;

		for (i = 0; strng[i]; i++)
			counts[strng[i]]++;

		for (i = 1, j = 0; i < 256; i++) {
			if (counts[i]) {
				str[j] = i;
				counts[j++] = counts[i];
			}
		}
		str[j] = '\0';  /* str contiene i caratteri distinti
                                 * counts[] le loro occorrenze
				 */

		for (i = 0, j = 0; i < length; i++) {
			curr[i] = str[j];
			pos[i] = j;
			if (!(--counts[j]))
				j++;
		}
		curr[i] = '\0';
		return curr;
	}

	for (j = length; j > 0;) {
		counts[ pos[--j]]++;

	for (i = ++pos[j]; str[i] && ! counts[i]; i++) ;
		if (0 != (curr[j] = str[i])) {
			--counts[i];
			pos[j] = i;

		for (++j, i = 0; j < length; j++) {
			for ( ; !counts[i]; i++) ;
                        curr[j] = str[i];
			--counts[i];
			pos[j] = i;
		}
		return curr;
		}
	}

return NULL;
}

void Permuta (char *srest)
{
int i;
char buff[MAXSTRLEN];
FILE *outfile;

	if ((outfile = IOFile(TEMPFILE,"w")) == NULL) return;
	i = strlen(srest);
	sprintf(buff,"%s\n",chouse_n(srest,i));
	fputs(buff,outfile);
	while ((srest = chouse_n(NULL,i)) != NULL) {
		sprintf(buff,"%s\n",srest);
		fputs(buff,outfile);
	}
	fclose(outfile);
	StampaCol(TEMPFILE,1,&i,i,OFF,OFF,srest);
}
